// Package requests 处理请求数据和表单验证
package requests

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/saint-yellow/go-pl/toys/gohub/pkg/response"
	"github.com/thedevsaddam/govalidator"
)

// ValidatorFunc 验证函数类型
type ValidatorFunc func(interface{}, *gin.Context) map[string][]string

// Validate 控制器里调用示例：
//        if ok := requests.Validate(c, &requests.UserSaveRequest{}, requests.UserSave); !ok {
//            return
//        }
func Validate(c *gin.Context, obj interface{}, handler ValidatorFunc) bool {

    // 1. 解析请求，支持 JSON 数据、表单请求和 URL Query
    if err := c.ShouldBind(obj); err != nil {
        response.BadRequest(c, err, "请求解析错误，请确认请求格式是否正确。上传文件请使用 multipart 标头，参数请使用 JSON 格式。")
        return false
    }

    // 2. 表单验证
    errs := handler(obj, c)

    // 3. 判断验证是否通过
    if len(errs) > 0 {
        c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{
            "message": "请求验证不通过，具体请查看 errors",
            "errors":  errs,
        })
        return false
    }

    return true
}

func validate(data interface{}, rules govalidator.MapData, messages govalidator.MapData) map[string][]string {
	// 配置初始化
    opts := govalidator.Options{
        Data:          data,
        Rules:         rules,
        TagIdentifier: "valid", // 模型中的 Struct 标签标识符
        Messages:      messages,
    }

    // 开始验证
    return govalidator.New(opts).ValidateStruct()
}

func validateFile(c *gin.Context, data interface{}, rules govalidator.MapData, messages govalidator.MapData) map[string][]string {
    opts := govalidator.Options{
        Request:       c.Request,
        Rules:         rules,
        Messages:      messages,
        TagIdentifier: "valid",
    }
    // 调用 govalidator 的 Validate 方法来验证文件
    return govalidator.New(opts).Validate()
}
